#!/bin/env python
# -*- coding: utf-8 -*-

import re
import time
import os.path

from NetDisk import NetDisk
from NetDiskInfo163 import NetDiskInfo163
from HttpFetcher import HttpFetcher
from FileInfo163Parser import FileInfo163Parser

class NetDisk163(NetDisk):
	"""
	base class for access net disk
	"""
	
	def __init__(self, username, password):
		NetDisk.__init__(self, username + "@163.com", password)
		self.username = username
		self.password = password
		self.logon = HttpFetcher()
		self.http = HttpFetcher()
		# note: miss 'HttpOnly', trunk 'expires'
		self.cookie_pat = re.compile('(\w+)=([^;,]+)')
		self.cookie_dict = {}
		self.cookie = ""
		self.server = ""
		self.sid = ""
		self.parser = FileInfo163Parser()
		self.diskinfo = NetDiskInfo163()
		self.file_dict = {}
		
	def login(self):
		"""
		login mail
		"""
		self.get_province_cookie()	
		self.post_logon()
		location = self.get_relocate()
		self.relocate(location)
	
	def init_netdisk(self):
		"""
		init access net disk
		"""
		url =  '/netfolder/servlet/nfapp/main_info.html?sid=' + self.sid

	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
		             #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}
		self.cookie += 'Coremail.sid=' + self.sid + '; '
		self.cookie += 'mail_style=js35; '
		self.cookie += 'mail_uid=' + self.username + '@163.com; '
		self.cookie += 'mail_host=' + self.server + '; '
		self.cookie += 'MAIL163_SSN=' + self.username + '; '
		self.cookie += 'ntes_mail_firstpage=normal; '
		self.cookie += 'MAIL_SESS=' +  self.cookie_dict['NTES_SESS'] + '; '
		
		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, None, self.cookie)
		
		self.diskinfo.parse(cont)
		
		self.file_dict['/'] = self.diskinfo

	def list_root(self):
		"""
		list root of net disk
		"""
		url =  '/netfolder/servlet/nfapp/main_list.html'\
		       '?sid=' + self.sid + \
		       '&origin=' + self.server + \
		       'username=' + self.username + \
		       '&cosname=undefined&' + str(int(time.time() * 1000))
	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
		             #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}
		
		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, None, self.cookie)

		self.parser.file_list = []
		self.parser.feed(cont)
		
		for f in self.parser.file_list:
			self.file_dict['/' + f.name] = f
		
	def get_province_cookie(self):
		# GET http://adgeo.163.com/ad_cookies
		server = 'adgeo.163.com'
		url = '/ad_cookies'
		headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            'Referer'         : 'http://mail.163.com',
		            'Content-Type'    : 'application/x-www-form-urlencoded',
		            'Accept'          : '*/*',
		            'Accept-Encoding' : 'gzip,deflate',
		            'Accept-Language' : 'zh-CN',
		}
		
		self.http.connect(server)
		self.http.fetch(url, headers)
		
		cookies = self.http.resp.getheader('Set-Cookie')
		self.cookie_dict = dict(self.cookie_pat.findall(cookies))
		
	def post_logon(self):
		# POST http://reg.163.com/login.jsp?type=1&url=http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight%3D1%26verifycookie%3D1%26language%3D-1%26style%3D-1
		server = 'reg.163.com'
		url = "/login.jsp?type=1"\
		      "&url=http://entry.mail.163.com/coremail/fcg/ntesdoor2?"\
			  "lightweight%3D1%26verifycookie%3D1%26language%3D-1%26style%3D-1"
		data = "verifycookie=1&style=-1&product=mail163&savelogin="\
               "&url2=http%3A%2F%2Fmail.163.com%2Ferrorpage%2Ferr_163.htm"\
			   "&username=" + self.username + "&password=" + self.password + "&selType=-1"
		headers = {  #'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'
		            'Accept'          : '*/*',
		            'Referer'         : 'http://mail.163.com',
		            'Accept-Language' : 'zh-CN',
		            'Content-Type'    : 'application/x-www-form-urlencoded',
		            'Accept-Encoding' : 'gzip, deflate',
		            'User-Agent'      : 'Mozilla/5.0',
		            'Connection'      : 'Keep-Alive',
		            'Cache-Control'   : 'no-cache',
		}
		
		self.cookie += 'Province=' + self.cookie_dict['Province'] + '; '
		self.cookie += 'City=' + self.cookie_dict['City'] + '; '
		
		self.logon.connect(server, 443, ssl=True)
		self.logon.fetch(url, headers, data, self.cookie)
		
		cookies = self.logon.resp.getheader('Set-Cookie')
		self.cookie_dict.update(dict(self.cookie_pat.findall(cookies)))

	def get_relocate(self):
		# GET http://entry.mail.163.com/coremail/fcg/ntesdoor2?lightweight=1&verifycookie=1&language=-1&style=-1&username=fhsjadt
		server = "entry.mail.163.com"
		url = "/coremail/fcg/ntesdoor2?lightweight=1&verifycookie=1&language=-1&style=-1"
		url += "&username=" + self.username
		headers = { #'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'
		            'Accept'          : '*/*',
					'Accept-Language' : 'zh-CN', 
					'Accept-Encoding' : 'gzip, deflate',
					'User-Agent'      : 'Mozilla/5.0',
					'Connection'      : 'Keep-Alive',
		}

		self.cookie += 'NTES_SESS=' + self.cookie_dict['NTES_SESS'] + '; '
		self.cookie += 'S_INFO=' + self.cookie_dict['S_INFO'] + '; '
		self.cookie += 'P_INFO=' + self.cookie_dict['P_INFO'] + '; '
		self.cookie += 'ntes_mail_firstpage=normal; '
		self.cookie += 'logType=-1; '
		self.cookie += 'nts_mail_user=' + self.username + ':-1:0' + '; '
		
		self.http.connect(server)
		self.http.fetch(url, headers, None, self.cookie)
		
		location = self.http.resp.getheader('Location')

		cookies = self.http.resp.getheader('Set-Cookie')
		self.cookie_dict.update(dict(self.cookie_pat.findall(cookies)))
		
		return location
		
	def relocate(self, location):
		self.sid = self.cookie_dict['Coremail'].split('%')[1]

		# GET http://tg2a16.mail.163.com/js3/main.jsp?sid=SAiYCZCRhbRaneMbgZRRfdTJVewvZVDp
		self.server = location.split('/', 3)[2]
		url = '/' + location.split('/', 3)[3]
		#url = '/js3/main.jsp?sid=' + self.sid
		headers = { #'image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*'
		            'Accept'          : '*/*',
					'Accept-Language' : 'zh-CN', 
					'Accept-Encoding' : 'gzip, deflate',
					'User-Agent'      : 'Mozilla/5.0',
					'Connection'      : 'Keep-Alive',
		}
		self.cookie += 'Coremail=' + self.cookie_dict['Coremail'] + '; '
		self.cookie += 'cm_last_info=' + self.cookie_dict['cm_last_info'] + '; '
		
		self.http.connect(self.server)
		self.http.fetch(url, headers, None, self.cookie)

	def list_dir(self, dir):
		"""
		list one directory
		"""
		dir_id = self.file_dict[dir].id
		url =  '/netfolder/servlet/nfapp/main_list.html?sid=' + self.sid +\
               '&fid=' + dir_id + '&sort=date'
	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
			        'Cache-Control'   : 'max-age=0',
		            #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}
		
		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, None, self.cookie)
		
		self.parser.file_list = []
		self.parser.feed(cont)
		
		for f in self.parser.file_list:
			self.file_dict[dir + '/' + f.name] = f
		
	def download(self, netdisk_file, local_file=None):
		"""
		download one file from netdisk
		netdisk_file must be full path name
		local_files's dir must exist
		"""
		file_id = self.file_dict[netdisk_file].id
		url =  '/netfolder/servlet/nfapp/GetFile/' + os.path.basename(netdisk_file) +\
		       '?sid=' + self.sid + '&mid=' + file_id
	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
			        'Cache-Control'   : 'max-age=0',
		            #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}			
		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, None, self.cookie)
		
		if local_file == None:
			filename = os.path.basename(netdisk_file)
		else:
			filename = local_file
		
		f = open(filename, 'wb')
		f.write(cont)
		f.close()
		
	def upload(self, local_file, netdisk_file):
		"""
		upload one file to netdisk
		"""
		pass
		
	def mkdir(self, dir_name, netdisk_dir):
		"""
		mkdir in netdisk
		"""
		dir_id = self.file_dict[netdisk_dir].id
		url =  '/netfolder/servlet/nfapp/NewFolder?sid=' + self.sid +\
		       '&fid=' + dir_id + '&name=' + dir_name +\
		       '&backurl=http%3a%2f%2f' + self.server + \
		       '%2fnetfolder%2fservlet%2fnfapp%2fmain%5flist%2ehtml%3fsid%3d' + self.sid +\
		       '%26origin%3d' + self.server + '%26username%3d' + self.username +\
		       '%26cosname%3dundefined%26' + str(time.time() * 1000)
	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
			    'Cache-Control'   : 'max-age=0',
			    'Origin'          : 'http://' + self.server,
			    'Content-Type'    : 'application/x-www-form-urlencoded',
		            #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}			
		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, None, self.cookie)
	
	def remove(self, cur_dir, files):
		"""
		remove file(s) or directory from one directory
		"""
		dir_id = self.file_dict[cur_dir].id
		mids = ''
		for file in files:
			file = cur_dir + '/' + file
			mids += '&mid=' + self.file_dict[file].id

		url =  '/netfolder/servlet/nfapp/SubmitDelete?sid=' + self.sid
	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
			    'Cache-Control'   : 'max-age=0',
			    'Origin'          : 'http://' + self.server,
			    'Content-Type'    : 'application/x-www-form-urlencoded',
		            #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}
		
		data = 'sid=' + self.sid + '&backurl=http%3A%2F%2F' + self.server + \
		       '%2Fnetfolder%2Fservlet%2Fnfapp%2Fmain_list.html%3Fsid%3D'+ self.sid + \
		       '%26fid%3D' + dir_id + '%26sort%3Ddate' + mids +\
		       'E&dest=&keyword='
			
		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, data, self.cookie)
				
	def move(self, srcdir, files, dstdir):
		"""
		move file(s) to directory
		"""
		src_dir_id = self.file_dict[srcdir].id
		dst_dir_id = self.file_dict[dstdir].id
		mids = ''
		for file in files:
			file = srcdir + '/'+ file
			mids += '&mid=' + self.file_dict[file].id
	
		url =  '/netfolder/servlet/nfapp/SubmitMove?sid=' + self.sid + '&dest=' + dst_dir_id
	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
		            'Cache-Control'   : 'max-age=0',
		            'Origin'          : 'http://' + self.server,
		            'Content-Type'    : 'application/x-www-form-urlencoded',
		            #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}
		data = 'sid=' + self.sid + '&backurl=http%3A%2F%2F' + self.server + \
		       '%2Fnetfolder%2Fservlet%2Fnfapp%2Fmain_list.html%3Fsid%3D'+ self.sid + \
		       '%26fid%3D' + src_dir_id + '%26sort%3Ddate' + mids + \
		       '&dest='+ dst_dir_id + '&keyword='
		
		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, data, self.cookie)
		
	def ping(self):
		"""
		keep connection, avoid service session timeout
		"""
		pass

	def logout(self):
		"""
		logout mail
		"""
		pass
		
	def add_contract(self, name, address):
		"""
		add contract
		"""
		url =  '/js3/s?sid=' + self.sid + '&func=pab:createContacts'
	   	headers = { 'Connection'      : 'Keep-Alive',
		            'User-Agent'      : 'Mozilla/5.0',
		            #'Referer'         : 'http://tg1a4.mail.163.com/js3/index.jsp?sid=GAbdXJQQkdbKYaHIeJQQNDNBVHXKBspH'
			        'Content-Type'    : 'application/xml',
		            #'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
		            'Accept'          : '*/*',
		            'Accept-Language' : 'zh-CN,zh;q=0.8', 
		            'Accept-Encoding' : 'gzip, deflate',
		            'Accept-Charset'  : 'GBK,utf-8;q=0.7,*;q=0.3'
		}
		
		data = """<?xml version="1.0"?><object><array name="items"><object><string name="FN">""" + name + \
		       """</string><string name="EMAIL;PREF">""" + address + \
			   """</string><string name="EMAIL;BAK1"></string><string name="EMAIL;BAK2"></string><string name="TEL;HOME;VOICE"></string><string name="TEL;CELL"></string><string name="TEL;WORK;VOICE"></string><string name="PC;HOME"></string><string name="URL"></string><string name="ORGNAME"></string><string name="ORG"></string><string name="TITLE"></string><string name="ADR;WORK"></string><string name="PC;WORK"></string><string name="TEL;WORK;FAX"></string><string name="ZS"></string><array name="groups"/><string name="ADR;HOME">;;;;;;CI</string><string name="ICQ"></string><string name="JINIAN"></string></object></array></object>"""

		#self.http.connect(self.server)
		cont = self.http.fetch(url, headers, data, self.cookie)
